001 /*
002 * Copyright 2005 Stephen J. McConnell.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
013 * implied.
014 *
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018
019 package net.dpml.lang;
020
021 import java.util.Arrays;
022
023 /**
024 * A object resolvable from primitive arguments.
025 *
026 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a>
027 * @version 1.0.2
028 */
029 public class ValueDirective extends AbstractDirective
030 {
031 private final String m_method;
032 private final String m_target;
033 private final String m_value;
034 private final ValueDirective[] m_args;
035 private final boolean m_compound;
036
037 /**
038 * Create a new value descriptor using the default java.lang.String class as the base type.
039 * @param value the construct value
040 */
041 public ValueDirective( String value )
042 {
043 this( null, null, value );
044 }
045
046 /**
047 * Create a new construct using a supplied target definition. The target argument
048 * may be either a classname or a symbolic object reference in the form ${[key]}.
049 *
050 * @param target a classname or symbolic object reference
051 * @param value the construct value
052 */
053 public ValueDirective( String target, String value )
054 {
055 this( target, null, value );
056 }
057
058 /**
059 * Create a new construct using a supplied target defintion. The target argument
060 * may be either a classname or a symbolic reference in the form ${[key]}. If the
061 * argument is symbolic it is resolved relative to a context map supplied by the
062 * application resolving construct values. If the construct value is symbolic
063 * the implementation will attempt to expand the reference relative to a context
064 * map (if supplied) otherwise the implementation will attempt to expand the value
065 * using system properties.
066 *
067 * @param target a classname or symbolic reference
068 * @param method the method to invoke on the target
069 * @param value the construct value
070 */
071 public ValueDirective( String target, String method, String value )
072 {
073 super();
074 m_target = target;
075 m_method = method;
076 m_value = value;
077 m_args = new ValueDirective[0];
078 m_compound = false;
079 }
080
081 /**
082 * Create a new construct using a supplied target defintion. The target argument
083 * may be either a classname or a symbolic reference in the form ${[key]}. If the
084 * argument is symbolic it is resolved relative to a context map supplied by the
085 * application resolving construct values. Instance values resolved from the
086 * supplied Value[] will be used as constructor arguments when resolving the target.
087 *
088 * @param target the construct classname
089 * @param args an array of unresolved parameter values
090 */
091 public ValueDirective( String target, ValueDirective[] args )
092 {
093 this( target, null, args );
094 }
095
096 /**
097 * Create a new construct using a supplied target defintion. The target argument
098 * may be either a classname or a symbolic reference in the form ${[key]}. If the
099 * argument is symbolic it is resolved relative to a context map supplied by the
100 * application resolving construct values. Instance values resolved from the
101 * supplied Value[] will be used as method arguments when resolving the target.
102 *
103 * @param target the construct classname
104 * @param method the method to invoke on the target
105 * @param args an array of unresolved parameter values
106 */
107 public ValueDirective( String target, String method, ValueDirective[] args )
108 {
109 super();
110 if( null == args )
111 {
112 m_args = new ValueDirective[0];
113 }
114 else
115 {
116 m_args = args;
117 }
118 m_value = null;
119 m_target = target;
120 m_method = method;
121 m_compound = true;
122 }
123
124 /**
125 * Return TRUE if this construct is a compund construct else FALSE.
126 * @return TRUE if this ia a compound construct
127 */
128 public boolean isCompound()
129 {
130 return m_compound;
131 }
132
133 /**
134 * Return the method name to be applied to the target object.
135 * @return the method name
136 */
137 public String getMethodName()
138 {
139 return m_method;
140 }
141
142 /**
143 * Return the set of nested values within this value.
144 * @return the nested values array
145 */
146 public ValueDirective[] getValueDirectives()
147 {
148 return m_args;
149 }
150
151 /**
152 * Return the base value of the resolved value.
153 * @return the base value
154 */
155 public String getBaseValue()
156 {
157 return m_value;
158 }
159
160 /**
161 * Return the classname of the resolved value.
162 * @return the classname
163 */
164 public String getTargetExpression()
165 {
166 return m_target;
167 }
168
169 /**
170 * Return a string representation of the construct.
171 * @return the string value
172 */
173 public String toString()
174 {
175 if( !m_compound )
176 {
177 return "value "
178 + " target: " + m_target
179 + " method: " + m_method
180 + " value: " + m_value;
181 }
182 else
183 {
184 return "value "
185 + " target: " + m_target
186 + " method: " + m_method
187 + " values: " + m_args.length;
188 }
189 }
190
191 /**
192 * Compare this instance with a supplied object for equality.
193 * @param other the other object
194 * @return true if the supplied instance is equal to this instance
195 */
196 public boolean equals( Object other )
197 {
198 if( super.equals( other ) && ( other instanceof ValueDirective ) )
199 {
200 ValueDirective construct = (ValueDirective) other;
201 if( !equals( m_target, construct.m_target ) )
202 {
203 return false;
204 }
205 if( m_compound != construct.m_compound )
206 {
207 return false;
208 }
209 if( !equals( m_method, construct.m_method ) )
210 {
211 return false;
212 }
213 if( m_compound )
214 {
215 return Arrays.equals( m_args, construct.m_args );
216 }
217 else
218 {
219 return equals( m_value, construct.m_value );
220 }
221 }
222 else
223 {
224 return false;
225 }
226 }
227
228 /**
229 * Compute the instance hashcode value.
230 * @return the hashcode
231 */
232 public int hashCode()
233 {
234 int hash = 0;
235 hash ^= hashValue( m_target );
236 hash ^= hashValue( m_method );
237 hash ^= hashArray( m_args );
238 hash ^= hashValue( m_value );
239 return hash;
240 }
241 }